#include <iostream>
#include <stdio.h>

class Base
{
	public:
		virtual void demo(void) {
			printf("Base demon\n");
		}

		virtual void demo_2(void) {
			printf("Base demon_2\n");
		}

		void demo_3(void) {
			printf("Nonvirtual Base demon_3\n");
		}
};

class Derived : public Base
{
	public:
		virtual void demo(void) {
			printf("Derived demon\n");
		}

		virtual void demo_2(void) {
			printf("Derived demon_2\n");
		}

		void demo_3(void) {
			printf("Nonvirtual Derived demon_3\n");
		}
};

int main()
{
	Base *p = new Base;
	
	p->demo();
	p->demo_2();
	p->demo_3();

	p = new Derived;
	p->demo();
	p->demo_2();
	p->demo_3();
}

/*
	Base demon
	Base demon_2
	Nonvirtual Base demon_3
	Derived demon
	Derived demon_2
	Nonvirtual Base demon_3		// 因为是 Base 指针，要是变成 Derived 指针，就是 Nonvirtual Derived demon_3 了。
 */

#if 0
/*
 * intel
 */
00000000000011a9 <main>:
    11a9:	f3 0f 1e fa          	endbr64 
    11ad:	55                   	push   %rbp		// rsp-=8, (rsp)=rbp ===> subq $8, %rsp, movq %rbp, (%rsp)
    11ae:	48 89 e5             	mov    %rsp,%rbp	// rbp=rsp
    11b1:	53                   	push   %rbx		// rsp-=8, (rsp)=rbx ===> subq $8, %rsp, movq %rbx, (%rsp)
    11b2:	48 83 ec 18          	sub    $0x18,%rsp	// rsp -= 0x18
    11b6:	bf 08 00 00 00       	mov    $0x8,%edi	// edi = 8
    11bb:	e8 d0 fe ff ff       	callq  1090 <_Znwm@plt>		/* new(8) */
    11c0:	48 89 c3             	mov    %rax,%rbx	// rbx = rax ---> new return value.
    11c3:	48 89 df             	mov    %rbx,%rdi	// rdi = rbx
    11c6:	e8 9b 01 00 00       	callq  1366 <_ZN4BaseC1Ev>	// Base(rdi)
    11cb:	48 89 5d e8          	mov    %rbx,-0x18(%rbp)     // rbp-0x18=rbx
    11cf:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax=rbp-0x18
    11d3:	48 8b 00             	mov    (%rax),%rax          // rax = (rax) = *(rbp-0x18)
    11d6:	48 8b 10             	mov    (%rax),%rdx          // rdx = ((rax)) = *(*(rbp-0x18))  
    11d9:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    11dd:	48 89 c7             	mov    %rax,%rdi            // rdi = rax
    11e0:	ff d2                	callq  *%rdx                // (rdx)(rdi)
    11e2:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rpb-0x18
    11e6:	48 8b 00             	mov    (%rax),%rax          // rax = (rax)
    11e9:	48 83 c0 08          	add    $0x8,%rax            // rax = (rax)+8
    11ed:	48 8b 10             	mov    (%rax),%rdx          // rdx = ((rax)+8)
    11f0:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    11f4:	48 89 c7             	mov    %rax,%rdi            // rdi = rax
    11f7:	ff d2                	callq  *%rdx                // (rdx)(rdi)
    11f9:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    11fd:	48 89 c7             	mov    %rax,%rdi            // rdi = rax
    1200:	e8 01 01 00 00       	callq  1306 <_ZN4Base6demo_3Ev> // 1306(rdi)
    1205:	bf 08 00 00 00       	mov    $0x8,%edi            // edi = 8
    120a:	e8 81 fe ff ff       	callq  1090 <_Znwm@plt>     // new(8)
    120f:	48 89 c3             	mov    %rax,%rbx            // rbx = rax = return value
    1212:	48 89 df             	mov    %rbx,%rdi            // rdi = rbx
    1215:	e8 6a 01 00 00       	callq  1384 <_ZN7DerivedC1Ev> // Derived(rdi)
    121a:	48 89 5d e8          	mov    %rbx,-0x18(%rbp)       // rbp-0x18 = rbx
    121e:	48 8b 45 e8          	mov    -0x18(%rbp),%rax	    // rax = rbp-0x18
    1222:	48 8b 00             	mov    (%rax),%rax          // rax = (rax) = (rbp-0x18)
    1225:	48 8b 10             	mov    (%rax),%rdx          // rdx = ((rax)) = ((rbp-0x18))
    1228:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    122c:	48 89 c7             	mov    %rax,%rdi            // rdi = rax = rbp-0x18
    122f:	ff d2                	callq  *%rdx                // rdx(rdi)
    1231:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    1235:	48 8b 00             	mov    (%rax),%rax          // rax = (rax)
    1238:	48 83 c0 08          	add    $0x8,%rax            // rax = (rax)+8
    123c:	48 8b 10             	mov    (%rax),%rdx          // rdx = ((rax)+8)
    123f:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    1243:	48 89 c7             	mov    %rax,%rdi            // rdi = rax
    1246:	ff d2                	callq  *%rdx                // rdx(rdi)
    1248:	48 8b 45 e8          	mov    -0x18(%rbp),%rax     // rax = rbp-0x18
    124c:	48 89 c7             	mov    %rax,%rdi            // rdi = rax
    124f:	e8 b2 00 00 00       	callq  1306 <_ZN4Base6demo_3Ev> // 1306(rdi)
    1254:	b8 00 00 00 00       	mov    $0x0,%eax            // eax = 0
    1259:	48 83 c4 18          	add    $0x18,%rsp           // rsp += 0x18
    125d:	5b                   	pop    %rbx                 // rbx=(rsp), rsp+=8 ===> movq (%rsp), rbx addq $8, %rsp 
    125e:	5d                   	pop    %rbp                 // rbp=(rsp), rsp+=8 ===> movq (%rsp), rbp addq $8, %rsp
    125f:	c3                   	retq                        // pop %rip  ===> rip = (rsp), rsp+=8 

00000000000012c6 <_ZN4Base4demoEv>:
    12c6:	f3 0f 1e fa          	endbr64 
    12ca:	55                   	push   %rbp                // rsp-=8, (rsp)=rbp ===> sub $8, %rsp; mov %rbp, (%rsp)
    12cb:	48 89 e5             	mov    %rsp,%rbp           // rbp = rsp
    12ce:	48 83 ec 10          	sub    $0x10,%rsp          // rsp -= 0x10
    12d2:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)     // rbp-0x8 = rdi = this
    12d6:	48 8d 3d 28 0d 00 00 	lea    0xd28(%rip),%rdi        # 2005 <_ZStL19piecewise_construct+0x1>
    12dd:	e8 ce fd ff ff       	callq  10b0 <puts@plt>     // puts(rdi)
    12e2:	90                   	nop
    12e3:	c9                   	leaveq                     // mov %ebp, %esp  pop %ebp
    12e4:	c3                   	retq					   // pop %rip  ===> rip = (rsp), rsp+=8 
    12e5:	90                   	nop

00000000000012e6 <_ZN4Base6demo_2Ev>:
    12e6:	f3 0f 1e fa          	endbr64 
    12ea:	55                   	push   %rbp				// rsp-=8, (rsp)=rbp ===> sub $8, rsp; mov %rbp, (rsp)
    12eb:	48 89 e5             	mov    %rsp,%rbp		// rbp = rsp
    12ee:	48 83 ec 10          	sub    $0x10,%rsp		// rsp -= 0x10
    12f2:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)	// rbp-0x8 = rdi = parameter1 = this
    12f6:	48 8d 3d 13 0d 00 00 	lea    0xd13(%rip),%rdi        # 2010 <_ZStL19piecewise_construct+0xc>
    12fd:	e8 ae fd ff ff       	callq  10b0 <puts@plt>	// puts(rdi)
    1302:	90                   	nop
    1303:	c9                   	leaveq					// mov %ebp, %esp; pop %ebp
    1304:	c3                   	retq					// pop %rip ===> rip = (rsp); rsp+=8
    1305:	90                   	nop

0000000000001306 <_ZN4Base6demo_3Ev>:
    1306:	f3 0f 1e fa          	endbr64 
    130a:	55                   	push   %rbp				// rsp-=8, (rsp)=rbp
    130b:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    130e:	48 83 ec 10          	sub    $0x10,%rsp		// rsp-=0x10
    1312:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)	// rbp-0x8=rdi
    1316:	48 8d 3d 00 0d 00 00 	lea    0xd00(%rip),%rdi        # 201d <_ZStL19piecewise_construct+0x19>
    131d:	e8 8e fd ff ff       	callq  10b0 <puts@plt>	// puts(rdi)
    1322:	90                   	nop
    1323:	c9                   	leaveq					// mov %ebp, %esp; pop %ebp
    1324:	c3                   	retq					// pop %rip ===> rip = (rsp); rsp+=8
    1325:	90                   	nop

0000000000001326 <_ZN7Derived4demoEv>:
    1326:	f3 0f 1e fa          	endbr64 
    132a:	55                   	push   %rbp				// rsp-=8, (rsp)=rbp
    132b:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    132e:	48 83 ec 10          	sub    $0x10,%rsp		// rsp-=0x10
    1332:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)	// rbp-0x8=rdi
    1336:	48 8d 3d f8 0c 00 00 	lea    0xcf8(%rip),%rdi        # 2035 <_ZStL19piecewise_construct+0x31>
    133d:	e8 6e fd ff ff       	callq  10b0 <puts@plt>	// puts(rdi)
    1342:	90                   	nop
    1343:	c9                   	leaveq 
    1344:	c3                   	retq   
    1345:	90                   	nop

0000000000001346 <_ZN7Derived6demo_2Ev>:
    1346:	f3 0f 1e fa          	endbr64 
    134a:	55                   	push   %rbp
    134b:	48 89 e5             	mov    %rsp,%rbp
    134e:	48 83 ec 10          	sub    $0x10,%rsp
    1352:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)
    1356:	48 8d 3d e6 0c 00 00 	lea    0xce6(%rip),%rdi        # 2043 <_ZStL19piecewise_construct+0x3f>
    135d:	e8 4e fd ff ff       	callq  10b0 <puts@plt>
    1362:	90                   	nop
    1363:	c9                   	leaveq 
    1364:	c3                   	retq   
    1365:	90                   	nop

0000000000001366 <_ZN4BaseC1Ev>:
    1366:	f3 0f 1e fa          	endbr64 
    136a:	55                   	push   %rbp
    136b:	48 89 e5             	mov    %rsp,%rbp
    136e:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)		// rbp-0x8=rdi = parameter = this
    1372:	48 8d 15 e7 29 00 00 	lea    0x29e7(%rip),%rdx        # 3d60 <_ZTV4Base+0x10> // rdx=rip+0x29e7
    1379:	48 8b 45 f8          	mov    -0x8(%rbp),%rax		// rax=rbp-0x8=this
    137d:	48 89 10             	mov    %rdx,(%rax)			// [this]=rdx
    1380:	90                   	nop
    1381:	5d                   	pop    %rbp
    1382:	c3                   	retq   
    1383:	90                   	nop

0000000000001384 <_ZN7DerivedC1Ev>:
    1384:	f3 0f 1e fa          	endbr64 
    1388:	55                   	push   %rbp
    1389:	48 89 e5             	mov    %rsp,%rbp
    138c:	48 83 ec 10          	sub    $0x10,%rsp
    1390:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)		// rbp-0x8=rdi=this
    1394:	48 8b 45 f8          	mov    -0x8(%rbp),%rax		// rax=this
    1398:	48 89 c7             	mov    %rax,%rdi			// rdi=this
    139b:	e8 c6 ff ff ff       	callq  1366 <_ZN4BaseC1Ev>	// base()
    13a0:	48 8d 15 99 29 00 00 	lea    0x2999(%rip),%rdx        # 3d40 <_ZTV7Derived+0x10>	// rdx=rip+0x2999
    13a7:	48 8b 45 f8          	mov    -0x8(%rbp),%rax		// rax=this
    13ab:	48 89 10             	mov    %rdx,(%rax)			// [tish]=rdx
    13ae:	90                   	nop
    13af:	c9                   	leaveq 
    13b0:	c3                   	retq   
    13b1:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    13b8:	00 00 00 
    13bb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)


/*
 * arm
 */
000000000040088c <main>:
  40088c:	a9bd7bfd 	stp	x29, x30, [sp, #-48]!
  400890:	910003fd 	mov	x29, sp						// fp = sp
  400894:	f9000bf3 	str	x19, [sp, #16]				// sp+16=x19
  400898:	d2800100 	mov	x0, #0x8                   	// #8
  40089c:	97ffffb9 	bl	400780 <_Znwm@plt>			// new(8)
  4008a0:	aa0003f3 	mov	x19, x0						// x19 = return value
  4008a4:	aa1303e0 	mov	x0, x19						// x0 = return value
  4008a8:	94000072 	bl	400a70 <_ZN4BaseC1Ev>		// Base(x0)
  4008ac:	f90017b3 	str	x19, [x29, #40]				// x29+40=x19
  4008b0:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40 = this
  4008b4:	f9400000 	ldr	x0, [x0]					// x0=[x29+40]
  4008b8:	f9400001 	ldr	x1, [x0]					// x1=[[x29+40]]
  4008bc:	f94017a0 	ldr	x0, [x29, #40]				// x0=[x29+40]
  4008c0:	d63f0020 	blr	x1							// x1(x0)
  4008c4:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40 = this
  4008c8:	f9400000 	ldr	x0, [x0]					// x0=[x29+40]
  4008cc:	91002000 	add	x0, x0, #0x8				// x0=x0+0x8=[x29+40]+0x8
  4008d0:	f9400001 	ldr	x1, [x0]					// x1=[[x29+40]+0x8]
  4008d4:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40 = this
  4008d8:	d63f0020 	blr	x1							// x1(x0)
  4008dc:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40 = this
  4008e0:	94000049 	bl	400a04 <_ZN4Base6demo_3Ev>	// demo_3(x0)
  4008e4:	d2800100 	mov	x0, #0x8                   	// #8
  4008e8:	97ffffa6 	bl	400780 <_Znwm@plt>			// new(8)
  4008ec:	aa0003f3 	mov	x19, x0						// x19=x0=return value = this
  4008f0:	aa1303e0 	mov	x0, x19						// x0=this
  4008f4:	94000068 	bl	400a94 <_ZN7DerivedC1Ev>	// Derived(x0)
  4008f8:	f90017b3 	str	x19, [x29, #40]				// x29+40=x19
  4008fc:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40
  400900:	f9400000 	ldr	x0, [x0]					// x0=[x29+40]
  400904:	f9400001 	ldr	x1, [x0]					// x1=[[x29+40]]
  400908:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40
  40090c:	d63f0020 	blr	x1							// x1(x0)
  400910:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40
  400914:	f9400000 	ldr	x0, [x0]					// x0=[x29+40]
  400918:	91002000 	add	x0, x0, #0x8				// x0+=8=[x29+40]+0x8
  40091c:	f9400001 	ldr	x1, [x0]					// x1=[[x29+40]+0x8]
  400920:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40
  400924:	d63f0020 	blr	x1							// x1(x0)
  400928:	f94017a0 	ldr	x0, [x29, #40]				// x0=x29+40
  40092c:	94000036 	bl	400a04 <_ZN4Base6demo_3Ev>	// demo_3(x0)
  400930:	52800000 	mov	w0, #0x0                   	// #0
  400934:	f9400bf3 	ldr	x19, [sp, #16]
  400938:	a8c37bfd 	ldp	x29, x30, [sp], #48
  40093c:	d65f03c0 	ret

00000000004009bc <_ZN4Base4demoEv>:
  4009bc:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  4009c0:	910003fd 	mov	x29, sp						// x29=fp=sp
  4009c4:	f9000fa0 	str	x0, [x29, #24]				// x29+24=x0=this
  4009c8:	90000000 	adrp	x0, 400000 <_init-0x6d8>
  4009cc:	912e0000 	add	x0, x0, #0xb80
  4009d0:	97ffff68 	bl	400770 <puts@plt>			// puts(x0)
  4009d4:	d503201f 	nop
  4009d8:	a8c27bfd 	ldp	x29, x30, [sp], #32
  4009dc:	d65f03c0 	ret

00000000004009e0 <_ZN4Base6demo_2Ev>:
  4009e0:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  4009e4:	910003fd 	mov	x29, sp
  4009e8:	f9000fa0 	str	x0, [x29, #24]
  4009ec:	90000000 	adrp	x0, 400000 <_init-0x6d8>
  4009f0:	912e4000 	add	x0, x0, #0xb90
  4009f4:	97ffff5f 	bl	400770 <puts@plt>
  4009f8:	d503201f 	nop
  4009fc:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400a00:	d65f03c0 	ret

0000000000400a04 <_ZN4Base6demo_3Ev>:
  400a04:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400a08:	910003fd 	mov	x29, sp
  400a0c:	f9000fa0 	str	x0, [x29, #24]
  400a10:	90000000 	adrp	x0, 400000 <_init-0x6d8>
  400a14:	912e8000 	add	x0, x0, #0xba0
  400a18:	97ffff56 	bl	400770 <puts@plt>
  400a1c:	d503201f 	nop
  400a20:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400a24:	d65f03c0 	ret

0000000000400a28 <_ZN7Derived4demoEv>:
  400a28:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400a2c:	910003fd 	mov	x29, sp
  400a30:	f9000fa0 	str	x0, [x29, #24]
  400a34:	90000000 	adrp	x0, 400000 <_init-0x6d8>
  400a38:	912ee000 	add	x0, x0, #0xbb8
  400a3c:	97ffff4d 	bl	400770 <puts@plt>
  400a40:	d503201f 	nop
  400a44:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400a48:	d65f03c0 	ret

0000000000400a4c <_ZN7Derived6demo_2Ev>:
  400a4c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400a50:	910003fd 	mov	x29, sp
  400a54:	f9000fa0 	str	x0, [x29, #24]
  400a58:	90000000 	adrp	x0, 400000 <_init-0x6d8>
  400a5c:	912f2000 	add	x0, x0, #0xbc8
  400a60:	97ffff44 	bl	400770 <puts@plt>
  400a64:	d503201f 	nop
  400a68:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400a6c:	d65f03c0 	ret

0000000000400a70 <_ZN4BaseC1Ev>:
  400a70:	d10043ff 	sub	sp, sp, #0x10
  400a74:	f90007e0 	str	x0, [sp, #8]			// sp+8=x0=this
  400a78:	90000000 	adrp	x0, 400000 <_init-0x6d8> // x0=400000
  400a7c:	91302001 	add	x1, x0, #0xc08			// x1=400c08
  400a80:	f94007e0 	ldr	x0, [sp, #8]			// x0=sp+8=this
  400a84:	f9000001 	str	x1, [x0]				// [this]=x1
  400a88:	d503201f 	nop
  400a8c:	910043ff 	add	sp, sp, #0x10
  400a90:	d65f03c0 	ret

0000000000400a94 <_ZN7DerivedC1Ev>:
  400a94:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400a98:	910003fd 	mov	x29, sp
  400a9c:	f9000fa0 	str	x0, [x29, #24]			// x29+24=x0=this
  400aa0:	f9400fa0 	ldr	x0, [x29, #24]			// x0=this
  400aa4:	97fffff3 	bl	400a70 <_ZN4BaseC1Ev>	// base()
  400aa8:	90000000 	adrp	x0, 400000 <_init-0x6d8>	// x0=400000
  400aac:	912fa001 	add	x1, x0, #0xbe8			// x1=400be8
  400ab0:	f9400fa0 	ldr	x0, [x29, #24]			// x0=x29+24=this
  400ab4:	f9000001 	str	x1, [x0]				// [this]=x1
  400ab8:	d503201f 	nop
  400abc:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400ac0:	d65f03c0 	ret
  400ac4:	00000000 	.inst	0x00000000 ; undefined

 #endif
